package com.eva.androidlibrary.widget.tabhost;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

/**
 * Tab host
 *
 * @author GUXIA318
 * @date 2015-09-15 16:35
 */
public class TabHostLayout extends LinearLayout {

    public static final int INVALID_POSITION = -1;
    private int mMotionPosition = INVALID_POSITION;

    private TabHostLayoutAdapter mAdapter = null;
    private OnTabHostSelectedChangedListener mListener;

    public interface OnTabHostSelectedChangedListener {

        void onSelected(View view, int position);
    }


    private DataSetObserver mDataSetObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            // 通知界面刷新
            dataSetChanged();
        }
    };

    public TabHostLayout(@NonNull Context context) {
        this(context, null);
    }

    public TabHostLayout(@NonNull Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TabHostLayout(@NonNull Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setOrientation(HORIZONTAL);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public TabHostLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.setOrientation(HORIZONTAL);
    }

    public void setAdapter(TabHostLayoutAdapter adapter) {
        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        this.mAdapter = adapter;
        this.mAdapter.registerDataSetObserver(mDataSetObserver);
        this.mAdapter.notifyDataSetChanged();
    }

    public void setOnTabHostItemSelectedListener(OnTabHostSelectedChangedListener listener) {
        this.mListener = listener;
    }

    public void setTabSelected(int position) {
        if (position < 0 || position > getChildCount() - 1) {
            return;
        }
        onTabChanged(position);
    }

    protected void dataSetChanged() {
        final int childCount = getChildCount();

        if (mAdapter == null || mAdapter.getCount() <= 0) {
            if (childCount > 0) {
                removeAllViews();
            }
            return;
        }

        final int newCount = mAdapter.getCount();
        if (newCount > 0) {
            final int N = Math.min(newCount, childCount);
            for (int i = 0; i < N; i++) {
                View child = getChildAt(i);
                detachViewFromParent(child);
                child = mAdapter.getTab(i, mMotionPosition == i, child, this);
                LinearLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
                lp.weight = 1;
                attachViewToParent(child, i, child.getLayoutParams());
            }
        }

        int delta = newCount - childCount;
        if (delta > 0) {
            final int newStartIndex = childCount;
            for (int i = newStartIndex; i < newCount; i++) {
                View child = mAdapter.getTab(i, mMotionPosition == i, null, this);
                LinearLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (lp == null) {
                    lp = generateDefaultLayoutParams();
                }
                lp.weight = 1;
                addViewInLayout(child, i, lp);
            }
        } else if (delta < 0) {
            removeViewsInLayout(newCount, Math.abs(delta));
        }
        requestLayout();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
            mDataSetObserver = null;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        final int actionMasked = ev.getActionMasked();
        switch (actionMasked) {
            case MotionEvent.ACTION_DOWN:
                final int x = (int) ev.getX();
                final int y = (int) ev.getY();
                int position = findMotionPosition(x, y);
                final int childCount = getChildCount();
                if (position >= 0 && position < childCount) {
                    onTabChanged(position);
                    return true;
                }
        }
        return false;
    }

    private int findMotionPosition(int x, int y) {
        final int childCount = getChildCount();
        if (childCount > 0) {
            for (int i = 0; i < childCount; i++) {
                final View v = getChildAt(i);
                if (x <= v.getRight() && x >= v.getLeft() && y <= v.getBottom() && y >= v.getTop()) {
                    return i;
                }
            }
        }
        return INVALID_POSITION;
    }

    protected void onTabChanged(int position) {
        this.mMotionPosition = position;
        final int childCount = getChildCount();
        if (mAdapter != null && mMotionPosition != INVALID_POSITION && mMotionPosition < childCount) {
            final View child = getChildAt(mMotionPosition);
            for (int i = 0; i < childCount; i++) {
                View v = getChildAt(i);
                v.setSelected(i == mMotionPosition);
            }
            if (mListener != null) {
                mListener.onSelected(child, mMotionPosition);
            }
        }
        mAdapter.notifyDataSetChanged();
    }

}
